package edu.ucla.whi.wanda;

import java.util.LinkedList;
import java.util.List;

import org.restlet.ext.wadl.ParameterInfo;
import org.restlet.ext.wadl.ParameterStyle;
import org.restlet.representation.Representation;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
import org.restlet.resource.Post;

import com.amazonaws.services.simpledb.model.Attribute;
import com.amazonaws.services.simpledb.model.DeleteAttributesRequest;
import com.amazonaws.services.simpledb.model.GetAttributesRequest;
import com.amazonaws.services.simpledb.model.PutAttributesRequest;
import com.amazonaws.util.json.JSONObject;

public abstract class BaseItemResource extends BaseResource {
	private String domain;
	private String itemIdKey;

	protected String itemId;
	
	public BaseItemResource(String itemIdKey, String domain) {
		super();
		
		this.domain = domain;
		this.itemIdKey = itemIdKey;
	}

	abstract protected List<ParameterInfo> newParams();

	protected List<ParameterInfo> postParams() {
		List<ParameterInfo> params = newParams();

		// make everything optional when update
		for (ParameterInfo param : params) {
			param.setRequired(false);
		}
		
		return params;
	}
	
	@Override
	protected List<ParameterInfo> outputParams() {
		List<ParameterInfo> params = newParams();
		
		// make everything "PLAIN"
		for (ParameterInfo param : params) {
			param.setStyle(ParameterStyle.PLAIN);
		}
		
		// add "Id" field
		params.add(0, new ParameterInfo("Id", true, "xsd:string", ParameterStyle.PLAIN, 
				"Unique identifier for the entry"));
		
		return params;
	}
	
	@Override
	protected void doInit() {
		super.doInit();
		
		itemId = (String) getRequestAttributes().get(itemIdKey);
	}

	protected static JSONObject getItem(String domain, String id) {
		return getItem(domain, id, false);
	}
	
	protected static JSONObject getItem(String domain, String id, boolean consistent) {
		GetAttributesRequest request = new GetAttributesRequest(domain, id);
		request.setConsistentRead(consistent);
		List<Attribute> attributes = getDB().getAttributes(request).getAttributes();
		
		return makeJson(id, attributes);
	}

	@Get("json")
	public String getItem() {
		JSONObject json = getItem(domain, itemId);
		if (json.length() < 2) {
			throw new RuntimeException("Item " + itemId + " doesn't exist!");
		}
		
		return json.toString();
	}
	
	@Post("txt:json")
	public String updateItem(Representation input) {
		getDB().putAttributes(new PutAttributesRequest(domain, itemId, 
				buildAttributesFromParams(postParams())));

		// for consistent read
		return getItem(domain, itemId, true).toString();
	}
	
	@Delete("json")
	public String removeItem() {
		String ret = getItem(domain, itemId).toString();
		getDB().deleteAttributes(new DeleteAttributesRequest(domain, itemId));

		return ret;
	}
}